package com.edu.exam.entity.assessment.technical;

import com.edu.exam.enums.common.QualityLevel;
import com.edu.exam.enums.common.WorkflowStatus;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import java.time.LocalDateTime;

/**
 * 质量评估实体类
 * 所属模块：B-02 题库管理模块
 * 对应数据库表：quality_evaluation
 *
 * 根据E-06-03质量监控子模块设计实现
 * 对应quality_evaluations数据表，用于存储基于质量数据和质量标准进行评估的结果
 *
 * @author System
 * @version 1.0.0
 */
@Entity
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class QualityEvaluation {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "evaluation_id", length = 32, unique = true, nullable = false)
    private String evaluationId;

    @Column(name = "data_id", length = 32, nullable = false)
    private String dataId;

    @Column(name = "standard_id", length = 32, nullable = false)
    private String standardId;

    @Enumerated(EnumType.STRING)
    @Column(name = "source_module", length = 20, nullable = false)
    private String sourceModule;

    @Column(name = "task_id", length = 32, nullable = false)
    private String taskId;

    @Column(name = "grader_id", length = 32, nullable = false)
    private String graderId;

    @Column(name = "overall_score", precision = 5, scale = 4, nullable = false)
    private Double overallScore;

    @Enumerated(EnumType.STRING)
    @Column(name = "score_level", length = 20, nullable = false)
    private QualityLevel scoreLevel;

    @Column(name = "criteria_scores", columnDefinition = "JSON", nullable = false)
    private String criteriaScores;

    @Column(name = "quality_metrics", columnDefinition = "JSON", nullable = false)
    private String qualityMetrics;

    @Enumerated(EnumType.STRING)
    @Column(name = "evaluation_status", length = 20, nullable = false)
    private WorkflowStatus evaluationStatus;

    @Column(name = "confidence_level", precision = 5, scale = 4)
    private Double confidenceLevel;

    @Column(name = "evaluated_by", length = 32, nullable = false)
    private String evaluatedBy;

    @Column(name = "evaluated_at", nullable = false)
    private LocalDateTime evaluatedAt;

    // 扩展字段
    @Column(name = "evaluation_method", length = 50)
    private String evaluationMethod; // 评估方法

    @Column(name = "evaluation_algorithm", length = 100)
    private String evaluationAlgorithm; // 评估算法

    @Column(name = "evaluation_version", length = 10)
    private String evaluationVersion; // 评估版本

    @Column(name = "evaluation_duration_ms")
    private Long evaluationDurationMs; // 评估耗时（毫秒）

    @Column(name = "evaluation_start_time")
    private LocalDateTime evaluationStartTime; // 评估开始时间

    @Column(name = "evaluation_end_time")
    private LocalDateTime evaluationEndTime; // 评估结束时间

    @Column(name = "data_collection_time")
    private LocalDateTime dataCollectionTime; // 数据采集时间

    @Column(name = "standard_version", length = 10)
    private String standardVersion; // 标准版本

    @Column(name = "standard_applied_at")
    private LocalDateTime standardAppliedAt; // 标准应用时间

    @Column(name = "weight_factors", columnDefinition = "JSON")
    private String weightFactors; // 权重因子

    @Column(name = "normalization_factors", columnDefinition = "JSON")
    private String normalizationFactors; // 标准化因子

    @Column(name = "benchmark_scores", columnDefinition = "JSON")
    private String benchmarkScores; // 基准分数

    @Column(name = "historical_comparison", columnDefinition = "JSON")
    private String historicalComparison; // 历史对比

    @Column(name = "peer_comparison", columnDefinition = "JSON")
    private String peerComparison; // 同行对比

    @Column(name = "trend_analysis", columnDefinition = "JSON")
    private String trendAnalysis; // 趋势分析

    @Column(name = "anomaly_flags", columnDefinition = "JSON")
    private String anomalyFlags; // 异常标记

    @Column(name = "quality_indicators", columnDefinition = "JSON")
    private String qualityIndicators; // 质量指标

    @Column(name = "performance_metrics", columnDefinition = "JSON")
    private String performanceMetrics; // 性能指标

    @Column(name = "improvement_suggestions", columnDefinition = "JSON")
    private String improvementSuggestions; // 改进建议

    @Column(name = "risk_factors", columnDefinition = "JSON")
    private String riskFactors; // 风险因子

    @Column(name = "mitigation_strategies", columnDefinition = "JSON")
    private String mitigationStrategies; // 缓解策略

    @Column(name = "quality_trend", length = 20)
    private String qualityTrend; // 质量趋势

    @Column(name = "trend_confidence", precision = 3, scale = 2)
    private Double trendConfidence; // 趋势置信度

    @Column(name = "predictive_score", precision = 5, scale = 4)
    private Double predictiveScore; // 预测分数

    @Column(name = "prediction_accuracy", precision = 3, scale = 2)
    private Double predictionAccuracy; // 预测准确性

    @Column(name = "review_required")
    private Boolean reviewRequired; // 是否需要审查

    @Column(name = "review_status", length = 20)
    private String reviewStatus; // 审查状态

    @Column(name = "reviewed_by", length = 32)
    private String reviewedBy; // 审查人

    @Column(name = "review_time")
    private LocalDateTime reviewTime; // 审查时间

    @Column(name = "review_comments", columnDefinition = "TEXT")
    private String reviewComments; // 审查意见

    @Column(name = "review_score_adjustment", precision = 5, scale = 4)
    private Double reviewScoreAdjustment; // 审查分数调整

    @Column(name = "final_score", precision = 5, scale = 4)
    private Double finalScore; // 最终分数

    @Column(name = "final_score_level", length = 20)
    private String finalScoreLevel; // 最终分数等级

    @Column(name = "appeal_status", length = 20)
    private String appealStatus; // 申诉状态

    @Column(name = "appeal_reason", columnDefinition = "TEXT")
    private String appealReason; // 申诉原因

    @Column(name = "appeal_resolved_by", length = 32)
    private String appealResolvedBy; // 申诉处理人

    @Column(name = "appeal_resolved_at")
    private LocalDateTime appealResolvedAt; // 申诉处理时间

    @Column(name = "appeal_resolution", columnDefinition = "TEXT")
    private String appealResolution; // 申诉处理结果

    @Column(name = "export_formats", columnDefinition = "JSON")
    private String exportFormats; // 导出格式

    @Column(name = "report_generated")
    private Boolean reportGenerated; // 是否已生成报告

    @Column(name = "report_generated_at")
    private LocalDateTime reportGeneratedAt; // 报告生成时间

    @Column(name = "report_template", length = 50)
    private String reportTemplate; // 报告模板

    @Column(name = "notification_sent")
    private Boolean notificationSent; // 是否已发送通知

    @Column(name = "notification_sent_at")
    private LocalDateTime notificationSentAt; // 通知发送时间

    @Column(name = "notification_channels", columnDefinition = "JSON")
    private String notificationChannels; // 通知渠道

    @Column(name = "feedback_received")
    private Boolean feedbackReceived; // 是否已收到反馈

    @Column(name = "feedback_received_at")
    private LocalDateTime feedbackReceivedAt; // 反馈接收时间

    @Column(name = "feedback_content", columnDefinition = "TEXT")
    private String feedbackContent; // 反馈内容

    @Column(name = "feedback_rating", precision = 2, scale = 1)
    private Double feedbackRating; // 反馈评分

    @Column(name = "archived")
    private Boolean archived; // 是否已归档

    @Column(name = "archive_time")
    private LocalDateTime archiveTime; // 归档时间

    @Column(name = "retention_days")
    private Integer retentionDays; // 保留天数

    @Column(name = "correlation_id", length = 100)
    private String correlationId; // 关联ID

    @Column(name = "batch_evaluation_id", length = 32)
    private String batchEvaluationId; // 批次评估ID

    @Column(name = "parent_evaluation_id", length = 32)
    private String parentEvaluationId; // 父评估ID

    @Column(name = "child_evaluation_ids", columnDefinition = "JSON")
    private String childEvaluationIds; // 子评估ID列表

    @PrePersist
    protected void onCreate() {
        LocalDateTime now = LocalDateTime.now();
        this.evaluatedAt = now;

        // 设置默认值
        if (this.evaluationStatus == null) {
            this.evaluationStatus = WorkflowStatus.COMPLETED;
        }
        if (this.confidenceLevel == null) {
            this.confidenceLevel = 1.0;
        }
        if (this.evaluationVersion == null) {
            this.evaluationVersion = "1.0";
        }
        if (this.reviewRequired == null) {
            this.reviewRequired = false;
        }
        if (this.appealStatus == null) {
            this.appealStatus = "NONE";
        }
        if (this.reportGenerated == null) {
            this.reportGenerated = false;
        }
        if (this.notificationSent == null) {
            this.notificationSent = false;
        }
        if (this.feedbackReceived == null) {
            this.feedbackReceived = false;
        }
        if (this.archived == null) {
            this.archived = false;
        }

        // 设置评估开始时间
        if (this.evaluationStartTime == null) {
            this.evaluationStartTime = now;
        }

        // 计算衍生字段
        calculateDerivedFields();
    }

    @PreUpdate
    protected void onUpdate() {
        // 更新衍生字段
        calculateDerivedFields();
    }

    /**
     * 计算衍生字段
     */
    private void calculateDerivedFields() {
        // 计算评估耗时
        if (this.evaluationStartTime != null && this.evaluationEndTime != null) {
            this.evaluationDurationMs = java.time.Duration.between(this.evaluationStartTime, this.evaluationEndTime).toMillis();
        }
        
        // 设置默认标准应用时间
        if (this.standardAppliedAt == null) {
            this.standardAppliedAt = LocalDateTime.now();
        }
        
        // 设置默认数据采集时间
        if (this.dataCollectionTime == null) {
            this.dataCollectionTime = LocalDateTime.now();
        }
        
        // 计算最终分数和等级
        if (this.reviewScoreAdjustment != null && this.overallScore != null) {
            this.finalScore = this.overallScore + this.reviewScoreAdjustment;
            // 基于最终分数设置等级（需要根据实际业务规则实现）
            if (this.finalScore != null) {
                this.finalScoreLevel = determineScoreLevel(this.finalScore);
            }
        } else if (this.overallScore != null) {
            this.finalScore = this.overallScore;
            this.finalScoreLevel = this.scoreLevel != null ? this.scoreLevel.toString() : null;
        }
    }

    /**
     * 根据分数确定等级（示例实现）
     */
    private String determineScoreLevel(Double score) {
        if (score >= 0.9) return "EXCELLENT";
        if (score >= 0.7) return "GOOD";
        if (score >= 0.5) return "AVERAGE";
        return "POOR";
    }

    // ===== 审计字段 =====

    /**
     * 创建时间
     */
    @CreationTimestamp
    @Column(name = "created_time", nullable = false, updatable = false)
    private LocalDateTime createdTime;

    /**
     * 更新时间
     */
    @UpdateTimestamp
    @Column(name = "updated_time", nullable = false)
    private LocalDateTime updatedTime;

    /**
     * 版本号（乐观锁）
     */
    @Version
    @Column(name = "version")
    private Integer version = 0;

    /**
     * 逻辑删除标记
     */
    @Column(name = "is_deleted", nullable = false)
    private Boolean isDeleted = false;
}